package com.heyi.nettylong.client.handler;


import com.alibaba.fastjson.JSONObject;
import com.heyi.nettylong.client.NettyClient;
import com.heyi.nettylong.client.listener.ChannelDataListener;
import com.heyi.nettylong.common.protobuf.Command;
import com.heyi.nettylong.common.protobuf.Message;
import com.heyi.nettylong.common.util.MD5Utils;
import com.heyi.nettylong.common.util.SpringBeanFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoop;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 处理登录验证的Handler
 *  @author dengfeng
 */
public class LoginHandler extends SimpleChannelInboundHandler<Message.MessageBase>{
	public Logger log = LoggerFactory.getLogger(this.getClass());

	NettyClient nettyClient;

	private final ChannelDataListener channelDataListener = SpringBeanFactory.getBean(ChannelDataListener.class);

	public LoginHandler(NettyClient nettyClient){
		this.nettyClient = nettyClient;
	}
	// 连接成功后，向server发送消息  
	@Override  
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		Message.MessageBase.Builder authMsg = Message.MessageBase.newBuilder();
		authMsg.setClientId(nettyClient.clientProperties.getClientId());
		authMsg.setCmd(Command.CommandType.AUTH);
		JSONObject jsonObject = new JSONObject();
		long timestamp = System.currentTimeMillis();
		jsonObject.put("sing", MD5Utils.md5(nettyClient.clientProperties.getClientId()+timestamp+ nettyClient.clientProperties.getClientSecret()));
		jsonObject.put("timestamp", timestamp);
		authMsg.setData(jsonObject.toJSONString());

		NettyClient.clientChannel = ctx.channel();
		ctx.writeAndFlush(authMsg.build());
	}

	/**
	 * 处理断开重连
	 */
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		if(channelDataListener != null){
			channelDataListener.disconnected();
		}
		log.info("-----netty channelInactive连接断开");
		if(NettyClient.connectAuthFail < 3) {
			Thread.sleep(1000);
			final EventLoop eventLoop = ctx.channel().eventLoop();
			super.channelInactive(ctx);
			nettyClient.doConnect(new Bootstrap(), eventLoop);
		}else{
			log.info("-----netty 验证不通过尝试3次后不再尝试");
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		log.info("-----netty exceptionCaught连接断开:"+cause.getMessage());
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, Message.MessageBase msg) throws Exception {
		if(msg.getCmd().equals(Command.CommandType.AUTH_BACK)){
			if(msg.getData().equals("success")){
				NettyClient.connectAuthFail = 0;
			}else{
				log.info("netty连接验证没通过：{}", msg.getData());
				NettyClient.connectAuthFail++;
			}
			if(channelDataListener != null){
				nettyClient.clientProperties.setToken(msg.getToken());
				channelDataListener.authority(msg.getData().equals("success"));
			}
		}else{
			if(ctx.channel().isOpen()){
				//触发下一个handler
				ctx.fireChannelRead(msg);
			}else {
				log.info("接收到其它类型消息[{}]且channel is not open", msg.getCmd());
			}
		}
		ReferenceCountUtil.release(msg);
	}
}
